home *** CD-ROM | disk | FTP | other *** search
- /*////////////////////////////////////////////////////////////////////
- // The Original Code is the "LastTab" extension for Mozilla Firefox.//
- // version 1.5 - October 26, 2005 //
- // The Initial Developer of the Original Code is Timothy Humphrey. //
- *////////////////////////////////////////////////////////////////////
- var TMP_LastTab = {
- CtrlKey : false,
- favorLeftToRightOrdering : true,
- handleCtrlTab : true,
- KeyboardNavigating : true,
- KeyLock : false,
- respondToMouseInTabList : true,
- showTabList : true,
- SuppressTabListReset : false,
- TabHistory : [],
- TabIndex : 0,
- TabList : null,
- TabListLock : false,
- _inited: false,
-
- DisplayTabList : function() {
- var element = document.documentElement;
- var tablist = this.TabList;
- var menuitem, tab, imageUrl, x, y, i, activeIndex;
-
- createCommonList(tablist, this.handleCtrlTab ? 3 : 2);
-
- var item = tablist.childNodes[this.TabIndexToMenuItem()];
- item.setAttribute("_moz-menuactive", "true");
- updateMenuItemActive(null, item);
-
- //moveTo() method introduces anomalies, e.g. hovering over location bar moves the popup; hiding and showing the popup works better
- document.popupNode = element;
- x = -element.boxObject.screenX;
- y = 10000;
- tablist.showPopup(element, x, y, "popup", null, null); //show offscreen to get popup measurements
- x = Math.round((window.outerWidth - tablist.boxObject.width) / 2) - (element.boxObject.screenX - window.screenX);
- y = Math.round((window.outerHeight - tablist.boxObject.height) / 2) - (element.boxObject.screenY - window.screenY);
- if(x + element.boxObject.screenX < 0)
- x = -element.boxObject.screenX;
- else if(x + element.boxObject.screenX + tablist.boxObject.width > window.screen.availWidth)
- x = window.screen.availWidth - tablist.boxObject.width - element.boxObject.screenX;
- if(y + element.boxObject.screenY < 0)
- y = -element.boxObject.screenY;
- else if(y + element.boxObject.screenY + tablist.boxObject.height > window.screen.availHeight)
- y = window.screen.availHeight - tablist.boxObject.height - element.boxObject.screenY;
- if(x == -1 && y == -1) //workaround special status of -1, -1 position in showPopup() method
- x = y = 0;
- this.SuppressTabListReset = true;
- tablist.hidePopup();
- this.SuppressTabListReset = false;
- tablist.showPopup(element, x, y, "popup", null, null);
-
- var ietab = "chrome://ietab/content/reloaded.html?url="
- if (gBrowser.currentURI.spec.indexOf(ietab) == 0)
- tablist.focus();
-
- this.TabListLock = true;
- },
-
- init : function() {
- this._inited = true;
- var browser = document.documentElement;
-
- this.TabList = document.getElementById("lasttabTabList");
-
- gBrowser.mTabBox._eventNode.removeEventListener("keypress", gBrowser.mTabBox, false);
- browser.addEventListener("keydown", this, true);
- browser.addEventListener("keypress", this, true);
- browser.addEventListener("keyup", this, true);
- this.TabList.addEventListener("DOMMenuItemActive", this, true);
- this.TabList.addEventListener("DOMMenuItemInactive", this, true);
-
- var tab = gBrowser.mCurrentTab;
- tab.__LastTab = true;
- this.TabHistory.push(tab);
- if (tab._tPos != 0) {
- // if session manager select other tab then the first one we need to build TabHistory in two steps
- // to maintain natural Ctrl-Tab order.
- // we call MaintainTabHistory from here the 2nd time is call from OnSelect.
- this.MaintainTabHistory(tab._tPos);
- }
-
- this.ReadPreferences();
- },
-
- deinit : function() {
- var browser = document.documentElement;
- browser.removeEventListener("keydown", this, true);
- browser.removeEventListener("keypress", this, true);
- browser.removeEventListener("keyup", this, true);
- this.TabList.removeEventListener("DOMMenuItemActive", this, true);
- this.TabList.removeEventListener("DOMMenuItemInactive", this, true);
- },
-
- handleEvent : function(event) {
- switch (event.type) {
- case "keydown":
- this.OnKeyDown(event);
- break;
- case "keypress":
- this.OnKeyPress(event);
- break;
- case "keyup":
- this.OnKeyUp(event);
- break;
- case "DOMMenuItemActive":
- this.ItemActive(event);
- break;
- case "DOMMenuItemInactive":
- this.ItemInactive(event);
- break;
- }
- },
-
- ItemActive : function(event) {
- updateMenuItemActive(event);
- if(this.respondToMouseInTabList) {
- if(this.KeyboardNavigating) {
- if(event.target.value != this.inverseIndex(this.TabIndex))
- this.TabList.childNodes[this.TabIndexToMenuItem()].setAttribute("_moz-menuactive", "false");
- this.KeyboardNavigating = false;
- }
- this.TabIndex = this.inverseIndex(event.target.value);
- }
- else {
- if(event.target.value != this.inverseIndex(this.TabIndex))
- event.target.setAttribute("_moz-menuactive", "false");
- }
- },
-
- ItemInactive : function(event) {
- updateMenuItemInactive(event);
- if(!this.respondToMouseInTabList && event.target.value == this.inverseIndex(this.TabIndex))
- event.target.setAttribute("_moz-menuactive", "true");
- },
-
- MaintainTabHistory : function(lastIndex) {
- var newTabs = [], tab, i;
-
- // Gather tab synchronization info
- if (typeof(lastIndex)=="undefined")
- lastIndex = gBrowser.mTabContainer.childNodes.length;
- for(i = 0; i < lastIndex; i++) {
- tab = gBrowser.mTabContainer.childNodes[i];
- if(!tab.__LastTab)
- newTabs[newTabs.length] = tab;
- }
-
- // Purge old tab info from history
- i = 0;
- try{
- while(i < this.TabHistory.length) {
- if(!this.TabHistory[i] || this.TabHistory[i].parentNode != gBrowser.mTabContainer)
- this.TabHistory.splice(i, 1);
- else
- i++;
- }
- } catch (e) {tmLog("error from Ctrl+Tab in MaintainTabHistory " + typeof(this.TabHistory[i]) + "\n" + e
- + "\n" + "this.TabHistory.length " + this.TabHistory.length + "\n" + "i " + i);}
-
- // Add new tabs to history
- if(newTabs.length > 0) {
- tab = this.TabHistory.pop();
- if(this.favorLeftToRightOrdering) {
- for(i = newTabs.length - 1; i >= 0; i--) {
- newTabs[i].__LastTab = true;
- this.TabHistory.push(newTabs[i]);
- }
- }
- else {
- for(i = 0; i < newTabs.length; i++) {
- newTabs[i].__LastTab = true;
- this.TabHistory.push(newTabs[i]);
- }
- }
- this.TabHistory.push(tab);
- }
- },
-
- OnKeyDown : function(event) {
- this.CtrlKey = event.ctrlKey && !event.altKey && !event.metaKey;
- },
-
- OnKeyPress : function _LastTab_OnKeyPress(event) {
- var tabCount = this.handleCtrlTab ? this.TabHistory.length : gBrowser.mTabs.length;
-
- if((this.handleCtrlTab || this.showTabList) && event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_TAB && event.ctrlKey && !event.altKey && !event.metaKey) {
- if(!this.KeyLock) {
- if (this.handleCtrlTab) {
- this.MaintainTabHistory();
- tabCount = this.TabHistory.length;
- this.TabIndex = tabCount - 1;
- } else {
- this.TabIndex = tabCount - 1 - gBrowser.mCurrentTab._tPos;
- }
- this.KeyLock = true;
- }
-
- if(this.TabListLock)
- this.TabList.childNodes[this.TabIndexToMenuItem()].setAttribute("_moz-menuactive", "false");
-
- if(event.shiftKey) {
- this.TabIndex++;
- if(this.TabIndex >= tabCount)
- this.TabIndex = 0;
- }
- else {
- this.TabIndex--;
- if(this.TabIndex < 0)
- this.TabIndex = tabCount - 1;
- }
-
- if(this.showTabList) {
- this.KeyboardNavigating = true;
- if(!this.TabListLock) {
- if(tabCount > 1)
- this.DisplayTabList();
- }
- else {
- var item = this.TabList.childNodes[this.TabIndexToMenuItem()];
- item.setAttribute("_moz-menuactive", "true");
- updateMenuItemActive(null, item);
- }
- }
- else {
- TMP_tabSelectedFromList(this.TabHistory[this.TabIndex]);
- }
-
- event.stopPropagation();
- event.preventDefault();
- }
- else {
- if(this.TabListLock)
- this.TabList.hidePopup();
-
- gBrowser.mTabBox.handleEvent(event);
- }
- },
-
- OnKeyUp : function _LastTab_OnKeyUp(event) {
- var keyReleased = event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_CONTROL;
-
- this.CtrlKey = event.ctrlKey && !event.altKey && !event.metaKey;
- if(keyReleased && this.TabListLock) {
- if(this.TabList.childNodes[this.TabIndexToMenuItem()].getAttribute("_moz-menuactive") == "true") {
- var tabToSelect = this.handleCtrlTab ? this.TabHistory[this.TabIndex] : gBrowser.mTabs[gBrowser.mTabs.length - 1 - this.TabIndex];
- TMP_tabSelectedFromList(tabToSelect);
- }
-
- updateMenuItemInactive(null);
- gBackupLabel=="";
-
- this.PushSelectedTab();
- this.TabList.hidePopup();
- }
- if(keyReleased && this.KeyLock) {
- this.PushSelectedTab();
- this.TabIndex = 0;
- this.KeyLock = false;
- }
- },
-
- OnMenuCommand : function _LastTab_OnMenuCommand(event) {
- if(this.respondToMouseInTabList) {
- var tabToSelect = this.handleCtrlTab ? this.TabHistory[event.target.value] : gBrowser.mTabs[event.target.value];
- TMP_tabSelectedFromList(tabToSelect);
- this.PushSelectedTab();
- }
- },
-
- OnPopupHidden : function() {
- if(!this.SuppressTabListReset) {
- var tablist = this.TabList;
-
- while(tablist.childNodes.length > 0)
- tablist.removeChild(tablist.childNodes[0]);
-
- this.TabListLock = false;
- this.TabIndex = 0;
- this.KeyLock = false;
-
- hideCommonList(tablist);
- }
- },
-
- OnSelect : function() {
- // session manager can select new tab before TMP_LastTab is init
- if (!this._inited)
- return;
-
- var tabCount = this.TabHistory.length;
-
- this.MaintainTabHistory();
- if(tabCount != gBrowser.mTabContainer.childNodes.length) {
- if(tabCount > gBrowser.mTabContainer.childNodes.length) {
- if(gBrowser.mTabContainer.childNodes.length == 1) {
- this.KeyLock = false;
- this.TabIndex = 0;
- }
- }
- this.PushSelectedTab();
- }
- else if(!this.KeyLock) {
- if(this.CtrlKey)
- this.KeyLock = true; //allow other tab navigation methods to work
- else
- this.PushSelectedTab();
- }
- },
-
- PushSelectedTab : function() {
- var selectedTab = gBrowser.mTabContainer.selectedItem;
- var tabCount, i;
-
- if(this.TabHistory[this.TabHistory.length - 1] != selectedTab) {
- tabCount = this.TabHistory.length;
- for(i = 0; i < tabCount; i++) {
- if(this.TabHistory[i] == selectedTab) {
- this.TabHistory.push(this.TabHistory.splice(i, 1)[0]);
- break;
- }
- }
- }
- },
-
- ReadPreferences : function() {
- /*
- * Build-in tabPreviews exist in Firefox 3.5+
- * when tabPreviews is on we disable our own function
- *
- * we use TMP_getBoolPref to make sure browser.ctrlTab.previews exist (for version before Firefox 3.5)
- */
- var mostRecentlyUsed = TMP_getBoolPref("", "browser.ctrlTab.previews", true);
- var tabPreviews = document.getElementById("ctrlTab-panel") && "ctrlTab" in window;
- if (tabPreviews) {
- var tabPreviewsCurentStatus = ctrlTab._recentlyUsedTabs ? true : false;
- tabPreviews = mostRecentlyUsed && tabxPrefs.getBoolPref("lasttab.tabPreviews");
- if (tabPreviewsCurentStatus != tabPreviews) {
- if (tabPreviews) {
- ctrlTab.init();
- ctrlTab._recentlyUsedTabs = [];
- for (var i = 0; i < this.TabHistory.length; i++) {
- ctrlTab._recentlyUsedTabs.unshift(this.TabHistory[i]);
- }
- }
- else
- ctrlTab.uninit();
- }
- }
-
- this.handleCtrlTab = !tabPreviews && mostRecentlyUsed;
- this.showTabList = !tabPreviews && tabxPrefs.getBoolPref("lasttab.showTabList");
- this.favorLeftToRightOrdering = tabxPrefs.getBoolPref("lasttab.favorLeftToRightOrdering");
- this.respondToMouseInTabList = tabxPrefs.getBoolPref("lasttab.respondToMouseInTabList");
- },
-
- TabIndexToMenuItem : function() {
- var activeIndex;
- if (this.handleCtrlTab)
- activeIndex = this.TabHistory.length - 1 - this.TabIndex;
- else
- activeIndex = gBrowser.mTabs.length - 1 - this.TabIndex;
- return activeIndex;
- },
-
- inverseIndex : function(index) {
- return this.handleCtrlTab ? index : gBrowser.mTabs.length - 1 - index;
- }
-
- }
-